4.3: Navigasi Layar
Materi:
- Menyediakan jalur bagi pengguna melalui aplikasi Anda
- Navigasi tombol-kembali
- Pola navigasi hierarkis
- Navigasi leluhur (tombol Naik)
- Navigasi turunan
- Navigasi lateral dengan tab dan gesek
- Praktik terkait
Menyediakan jalur bagi pengguna melalui aplikasi Anda
Pada tahap awal pengembangan aplikasi, Anda harus menentukan jalur yang harus digunakan pengguna melalui aplikasi Anda untuk melakukan sesuatu, seperti menyerahkan pesanan atau menjelajahi materi. Setiap jalur memungkinkan pengguna melakukan navigasi ke seluruh bagian, ke dalam, dan kembali dari tugas serta potongan materi yang berbeda-beda dalam aplikasi.
Dalam banyak kasus, Anda akan memerlukan sejumlah jalur berbeda melalui aplikasi Anda yang menawarkan tipe navigasi berikut:
- Navigasi kembali: Pengguna bisa mengarahkan kembali ke layar sebelumnya menggunakan tombol Kembali.
- Navigasi hierarkis: Pengguna bisa mengarahkan melalui hierarki layar yang disusun dengan layar induk untuk setiap rangkaian layar anak.
Navigasi tombol-kembali
Navigasi tombol-kembali—navigasi kembali melalui riwayat layar—sangat mengakar dalam sistem Android. Pengguna Android mengharapkan tombol Kembali di sudut kiri bawah setiap layar untuk membawa mereka ke layar sebelumnya. Serangkaian layar historis selalu dimulai dengan Peluncur atau Launcher pengguna (layar utama perangkat), seperti yang ditampilkan dalam gambar di bawah ini. Menekan Kembali beberapa kali akan mengembalikan pengguna ke Launcher.
Dalam gambar di atas:
- Mulai dari Launcher.
- Mengeklik tombol Kembali untuk mengarahkan ke layar sebelumnya.
Anda tidak harus mengelola tombol Kembali di aplikasi. Sistem akan menangani tugas dan back-stack—yakni daftar layar sebelumnya—secara otomatis. Tombol Kembali secara default cukup melintasi daftar layar ini, yang membuang layar saat ini dari daftar saat pengguna menekannya.
Akan tetapi, ada beberapa kasus di mana Anda ingin menggantikan perilaku tombol Kembali. Misalnya, jika layar Anda berisi browser web yang disematkan, tempat pengguna bisa berinteraksi dengan elemen laman untuk mengarahkan di antara laman web, Anda mungkin ingin memicu perilaku kembali default dari browser yang disematkan saat pengguna menekan tombol Kembali di perangkat.
Metode onBackPressed() dari kelas Activity dipanggil bila aktivitas mendeteksi bahwa pengguna menekan tombol Kembali. Implementasi default hanya mengakhiri aktivitas saat ini, namun Anda bisa menggantinya agar melakukan sesuatu:
@Override
public void onBackPressed() {
// Add the Back key handler here.
return;
}
Jika kode Anda memicu browser yang disematkan dengan perilakunya sendiri ke tombol Kembali, Anda harus mengembalikan perilaku tombol Kembali ke perilaku default sistem, jika pengguna menggunakan tombol Kembali untuk melebihi awal riwayat internal browser.
Pola navigasi hierarkis
Untuk memberi jalur bagi pengguna ke beragam layar aplikasi, praktik terbaiknya adalah menggunakan beberapa bentuk navigasi hierarkis. Layar aplikasi umumnya disusun dalam hierarki induk-anak, seperti yang ditampilkan dalam gambar di bawah ini:
Dalam gambar di atas:
- Layar induk. Layar induk (seperti layar utama aplikasi berita) memungkinkan navigasi turun ke layar anak.
- Aktivitas utama suatu aplikasi biasanya adalah layar induk.
- Implementasikan layar induk sebagai Activity dengan navigasi turunan ke satu atau beberapa layar anak.
- Saudara layar anak level pertama. Saudara adalah beberapa layar dalam posisi yang sama dalam hierarki dengan layar induk yang sama (seperti saudara kandung).
- Pada saudara level pertama, layar anak bisa berupa kumpulan layar yang mengumpulkan judul berita, seperti yang ditampilkan di atas.
- Implementasikan setiap layar anak sebagai Activity atau Fragment.
- Implementasikan navigasi lateral untuk mengarahkan dari satu saudara ke saudara lain pada level yang sama.
- Jika ada layar level kedua, layar anak level pertama akan menjadi induk bagi saudara layar anak level kedua. Implementasikan navigasi turunan untuk layar anak level kedua.
- Saudara layar anak level kedua. Dalam aplikasi berita dan aplikasi lainnya yang menawarkan beberapa level informasi, saudara layar anak level kedua mungkin menawarkan materi, misalnya cerita.
Anda bisa memungkinkan pengguna untuk mengarahkan naik dan turun dari suatu induk, dan menyamping di antara layar saudara:
- Navigasi turunan: Mengarahkan turun dari suatu layar induk ke layar anak.
- Navigasi leluhur: Mengarahkan naik dari suatu layar anak ke layar induk.
- Navigasi lateral: Mengarahkan dari satu saudara ke saudara yang lain (pada level yang sama).
Anda bisa menggunakan aktivitas utama (sebagai layar induk) kemudian aktivitas atau fragmen lainnya untuk mengimplementasikan hierarki layar dalam aplikasi.
Aktivitas utama dengan aktivitas lainnya
Jika saudara layar anak level pertama memiliki layar anak level lain di bawahnya, Anda harus mengimplementasikan layar level pertama sebagai aktivitas, sehingga daur hidupnya dikelola dengan benar sebelum memanggil layar anak level kedua.
Misalnya, dalam gambar di atas, layar induk kemungkinan besar adalah aktivitas utama. Aktivitas utama aplikasi (biasanya MainActivity.java) umumnya adalah layar induk untuk semua layar lain dalam aplikasi, dan Anda akan mengimplementasikan pola navigasi dalam aktivitas utama untuk memungkinkan pengguna berpindah ke aktivitas atau fragmen lain. Misalnya, Anda bisa mengimplementasikan navigasi menggunakan suatu Maksud yang akan memulai aktivitas.
Tip: Penggunaan suatu Maksud dalam aktivitas saat ini untuk memulai aktivitas lain akan menambahkan aktivitas saat ini ke tumpukan panggilan, sehingga tombol Kembali di aktivitas lain (yang dijelaskan di bagian sebelumnya) akan mengembalikan pengguna ke aktivitas saat ini.
Sebagaimana yang Anda pelajari sebelumnya, sistem Android memulai kode dalam suatu instance Aktivitas dengan metode callback yang mengelola daur hidup aktivitas untuk Anda. (Pelajaran sebelumnya membahas daur hidup aktivitas; untuk informasi selengkapnya, lihat "Mengelola Daur Hidup Aktivitas" di bagian Pelatihan pada Panduan Developer Android.)
Hierarki aktivitas induk dan anak didefinisikan dalam file AndroidManifest.xml. Misalnya, yang berikut ini mendefinisikan OrderActivity
sebagai anak dari MainActivity
induk:
<activity android:name=".OrderActivity"
android:label="@string/title_activity_order"
android:parentActivityName=
"com.example.android.droidcafe.MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity"/>
</activity>
Aktivitas utama dengan fragmen
Jika saudara layar anak tidak memiliki layar anak level lain di bawahnya, Anda bisa mengimplementasikannya sebagai fragmen. Fragmen menyatakan perilaku atau porsi antarmuka pengguna dalam suatu aktivitas. Anda bisa menganggap fragmen sebagai bagian modular dari aktivitas, yang memiliki daur hidup sendiri, menerima kejadian masukan sendiri, dan yang bisa Anda tambahkan atau buang saat aktivitas berjalan.
Anda bisa mengombinasikan beberapa fragmen dalam satu aktivitas tunggal. Misalnya, dalam layar saudara bagian yang menampilkan cerita dan diimplementasikan sebagai suatu aktivitas, Anda mungkin memiliki layar anak untuk klip video yang diimplementasikan sebagai fragmen. Anda harus mengimplementasikan suatu cara bagi pengguna untuk mengarah ke fragmen klip video, kemudian kembali ke aktivitas yang menampilkan cerita.
Navigasi leluhur (tombol Naik)
Dengan navigasi leluhur dalam hierarki multitier, Anda memungkinkan pengguna untuk naik ke atas dari bagian saudara ke saudara kumpulan, kemudian naik ke layar induk.
Dalam gambar di atas:
- Tombol Naik untuk navigasi leluhur dari saudara level pertama ke induk.
- Tombol Naik untuk navigasi leluhur dari saudara level kedua ke layar anak level pertama yang bertindak sebagai layar induk.
Tombol Naik digunakan untuk berpindah dalam aplikasi berdasarkan hubungan hierarki antar layar. Misalnya (denganmerujuk pada gambar di atas):
- Jika layar anak level pertama menawarkan judul untuk berpindah ke layar anak level kedua, saudara layar anak level kedua harus menawarkan tombol Naik yang akan mengembalikan ke layar anak level pertama, yang merupakan induk mereka bersama.
- Jika layar induk menawarkan navigasi ke saudara anak level pertama, maka saudara anak level pertama harus menawarkan tombol Naik yang mengembalikan ke layar induk.
- Jika layar induk adalah layar paling atas dalam aplikasi (yaitu, layar utama aplikasi), layar tersebut tidak boleh menawarkan tombol Naik.
Tip: Tombol Kembali di bawah layar berbeda dari tombol Naik. Tombol Kembali menyediakan navigasi ke layar mana pun yang Anda tampilkan sebelumnya. Jika Anda memiliki sejumlah layar anak yang bisa disusuri oleh pengguna menggunakan pola navigasi lateral (seperti yang dijelaskan nanti di bab ini), tombol Kembali akan mengirim pengguna kembali ke layar anak sebelumnya, bukan ke layar induk. Gunakan tombol Naik jika Anda ingin menyediakan navigasi leluhur dari layar anak kembali ke layar induk. Untuk informasi selengkapnya tentang navigasi Naik, lihat Menyediakan Navigasi Naik.
Lihat bab konsep "Menu" untuk detail mengenai cara mengimplementasikan bilah aplikasi. Untuk menyediakan tombol Naik bagi aktivitas layar anak, deklarasikan induk aktivitas sebagai MainActivity dalam file AndroidManifest.xml. Anda juga bisa menyetel android:label
ke judul layar aktivitas, seperti "Order Activity" (yang diekstrak ke dalam sumber daya string title_activity_order
dalam kode di bawah). Ikuti langkah-langkah ini untuk mendeklarasikan induk dalam AndroidManifest.xml:
- Buka AndroidManifest.xml
- Ubah elemen aktivitas untuk aktivitas layar anak (dalam contoh ini,
OrderActivity
) ke yang berikut ini:<activity android:name=".OrderActivity" android:label="@string/title_activity_order" android:parentActivityName= "com.example.android.optionsmenuorderactivity.MainActivity"> <meta-data android:name="android.support.PARENT_ACTIVITY" android:value=".MainActivity"/> </activity>
Layar anak ("Order Activity") kini menyertakan tombol Naik dalam bilah aplikasi (disorot dalam gambar di bawah ini), yang bisa diketuk oleh pengguna untuk mengarahkan kembali ke layar induk.
Navigasi turunan
Dengan navigasi turunan, Anda memungkinkan pengguna untuk pergi dari layar induk ke layar anak level pertama, dan dari layar anak level pertama turun ke layar anak level kedua.
Dalam gambar di atas:
- Navigasi turunan dari orang tua ke layar anak level pertama.
- Navigasi turunan dari judul pada layar anak level pertama ke layar anak level kedua.
Tombol atau target
Praktik terbaik untuk navigasi turunan dari layar induk ke saudara kumpulan adalah menggunakan tombol atau target sederhana seperti susunan gambar atau tombol ikonis (disebut juga dengan dasbor). Bila pengguna menyentuh tombol, layar saudara kumpulan akan membuka, yang akan mengganti (layar) konteks saat ini seluruhnya.
Tip: Tombol dan target sederhana jarang sekali digunakan untuk berpindah ke saudara bagian dalam suatu kumpulan. Lihat daftar, menu korsel, dan kartu di bagian berikutnya.
Dalam gambar di atas:
- Tombol pada layar induk.
- Target (Tombol gambar atau ikon) pada layar induk.
- Pola navigasi turunan dari layar induk ke saudara anak level pertama.
Dasbor biasanya memiliki dua atau tiga baris dan kolom, dengan target sentuh luas untuk membuatnya mudah digunakan. Dasbor adalah yang paling tepat bila setiap saudara kumpulan sama pentingnya. Anda bisa menggunakan LinearLayout, RelativeLayout, atau GridLayout. Lihat Layout untuk ringkasan cara kerja layout.
Panel samping navigasi
Panel samping navigasi adalah panel yang biasanya menampilkan opsi navigasi pada tepi kiri layar, seperti yang ditampilkan pada sisi kanan gambar di bawah. Panel ini paling sering tersembunyi, namun ditampilkan bila pengguna menggesekkan jari dari tepi kiri layar atau menyentuh ikon navigasi dalam bilah aplikasi, seperti yang ditampilkan pada samping kiri gambar di bawah ini.
Dalam gambar di atas:
- Ikon navigasi dalam bilah aplikasi
- Panel samping navigasi
- Item menu panel samping navigasi
Contoh bagus panel samping navigasi adalah aplikasi Gmail, yang menyediakan akses ke Inbox, folder email berlabel, dan setelan. Praktik terbaik untuk menggunakan panel samping navigasi adalah menyediakan navigasi turunan dari aktivitas induk ke semua aktivitas atau fragmen lain dalam aplikasi. Panel samping navigasi bisa menampilkan banyak target navigasi sekaligus—misalnya, bisa berisi tombol (seperti dasbor), tab, atau daftar item (panel samping Gmail).
Untuk membuat panel samping navigasi dalam aplikasi, Anda perlu melakukan yang berikut ini:
- Buat layout berikut:
- Panel samping navigasi sebagai tampilan akar layout aktivitas.
- Tampilan navigasi untuk panel samping itu sendiri.
- Layout bilah aplikasi yang akan menyertakan tombol ikon navigasi.
- Layout materi untuk aktivitas yang menampilkan panel samping navigasi.
- Layout untuk header panel samping navigasi.
- Isilah menu panel samping navigasi dengan judul item dan ikon.
- Persiapkan panel samping navigasi dan listener item dalam kode aktivitas.
- Tangani pemilihan item menu navigasi.
Membuat layout panel samping navigasi
Untuk membuat layout panel samping navigasi, gunakan DrawerLayout API yang tersedia dalam Pustaka Dukungan. Untuk spesifikasi desain, ikuti prinsip desain panel samping navigasi dalam panduan desain Panel Samping Navigasi.
Untuk menambahkan panel samping navigasi, gunakan DrawerLayout
sebagai tampilan akar layout aktivitas Anda. Di dalam DrawerLayout
, tambahkan satu tampilan yang berisi materi utama untuk layar (layout utama Anda saat panel samping disembunyikan) dan tampilan lain, umumnya NavigationView, yang berisi materi panel samping navigasi.
Tip: Untuk membuat layout Anda lebih mudah dipahami, gunakan tag include
untuk menyertakan layout XML dalam layout XML lainnya.
Misalnya, layout berikut menggunakan:
- Sebuah
DrawerLayout
sebagai akar layout aktivitas dalam activity_main.xml. - Materi utama layar didefinisikan dalam file layout app_bar_main.xml.
- NavigationView yang menyatakan menu navigasi standar yang bisa diisi oleh file XML sumber daya menu.
Lihat gambar di bawah yang menyangkut layout ini:
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="@layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
Dalam gambar di atas:
- DrawerLayout adalah tampilan akar layout aktivitas.
app_bar_main
(app_bar_main.xml) yang disertakan menggunakan CoordinatorLayout sebagai akarnya, dan mendefinisikan layout bilah aplikasi dengan Bilah Alat yang akan menyertakan ikon navigasi untuk membuka panel samping.- NavigationView mendefinisikan layout panel samping navigasi dan header-nya, serta menambahkan item menu ke panel.
Perhatikan hal berikut dalam layout activity_main.xml:
- Identitas
android:id
untuk tampilan DrawerLayout adalahdrawer_layout
. Anda akan menggunakan ID ini untuk membuat instance objekdrawer
dalam kode Anda. - Identitas
android:id
untukNavigationView
adalahnav_view
. Anda akan menggunakan ID ini untuk membuat instance objeknavigationView
dalam kode Anda. - Objek
NavigationView
harus menetapkan gravitasi horizontalnya dengan atributandroid:layout_gravity
. Gunakan nilai"start"
untuk atribut ini (bukan"left"
) sehingga jika aplikasi ini digunakan dengan bahasa kanan ke kiri (RTF), panel samping akan muncul di sisi kanan, buka di kiri.android:layout_gravity="start"
- Gunakan atribut
android:fitsSystemWindows="true"
untuk menyetel pengisiDrawerLayout
danNavigationView
untuk memastikan materi tidak menghamparkan jendela sistem.DrawerLayout
menggunakanfitsSystemWindows
sebagai tanda bahwa anaknya (seperti tampilan materi utama) perlu disisipkan, namun tetap menggambar latar belakang bilah status atas di ruang itu. Akibatnya, panel samping navigasi tampak tumpang tindih, namun tidak mengaburkan, bilah status atas yang tembus pandang. Sisipan yang Anda dapatkan darifitsSystemWindows
akan dikoreksi pada semua versi platform untuk memastikan materi Anda tidak tumpang tindih dengan komponen UI yang disediakan sistem.
Header panel samping navigasi
Objek NavigationView
menetapkan layout untuk header panel samping navigasi dengan atribut app:headerLayout="@layout/nav_header_main"
. File nav_header_main.xml mendefinisikan layout header ini untuk menyertakan ImageView
dan TextView
, yang umum untuk panel samping navigasi, namun Anda juga bisa menyertakan Tampilan lain.
Tip: Tinggi header harus 160 dp, yang harus Anda ekstrak menjadi sumber daya dimensi (nav_header_height
).
nav_header_main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/nav_header_height"
android:background="@drawable/side_nav_bar"
android:gravity="bottom"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:theme="@style/ThemeOverlay.AppCompat.Dark">
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="@dimen/nav_header_vertical_spacing"
android:src="@android:drawable/sym_def_app_icon" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/nav_header_vertical_spacing"
android:text="@string/my_app_title"
android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
</LinearLayout>
Layout bilah aplikasi
Tag include
dalam layout activity_main
menyertakan layout app_bar_main
, yang menggunakan CoordinatorLayout sebagai akarnya. File layout app_bar_main.xml mendefinisikan layout bilah aplikasi dengan kelas Toolbar seperti yang ditampilkan sebelumnya dalam bab tentang menu. Layout ini juga mendefinisikan tombol aksi mengambang, dan menggunakan tag include
untuk menyertakan content_main
layout (content_main.xml):
app_bar_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.example.android.navigationexperiments.MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_main" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
android:src="@android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>
Perhatikan yang berikut ini:
- Layout
app_bar_main
menggunakan CoordinatorLayout sebagai akarnya, dan menyertakan layoutcontent_main
. - Layout
app_bar_main
menggunakan atributandroid:fitsSystemWindows="true"
untuk menyetel pengisi bilah aplikasi guna memastikannya tidak menghamparkan jendela sistem seperti bilah status.
Layout materi untuk layar aktivitas utama
Layout di atas menggunakan tag include
untuk menyertakan layout content_main
, yang mendefinisikan layout layar aktivitas utama (content_main.xml). Dalam contoh layout di bawah ini, layar aktivitas utama menampilkan TextView yang menampilkan string "Hello World!":
content_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.example.android.navigationexperiments.MainActivity"
tools:showIn="@layout/app_bar_main">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
</RelativeLayout>
Perhatikan yang berikut ini:
- Layout
content_main
harus anak pertama dalamDrawerLayout
karena panel samping harus berada di atas materi. Dalam layout kami di atas, layoutcontent_main
disertakan dalam layoutapp_bar_main
, yang merupakan anak pertama. - Layout
content_main
menggunakan sebuah grup tampilanRelativeLayout
yang disetel untuk menyesuaikan dengan lebar dan panjang tampilan induk, karena layout ini menyatakan keseluruhan UI saat panel samping navigasi disembunyikan. - Perilaku layout untuk
RelativeLayout
disetel ke sumber daya string@string/appbar_scrolling_view_behavior
, yang mengontrol perilaku gulir layar sehubungan dengan bilah aplikasi di bagian atas. Perilaku ini didefinisikan oleh kelas AppBarLayout.ScrollingViewBehavior. Perilaku ini harus digunakan oleh Tampilan yang bisa menggulir secara vertikal—perilaku ini mendukung pengguliran tersarang untuk menggulir AppBarLayout yang seinduk secara otomatis.
Mengisi menu panel samping navigasi
Objek NavigationView
di layout activity_main
menetapkan item menu untuk panel samping navigasi dengan menggunakan pernyataan berikut:
app:menu="@menu/activity_main_drawer"
Item menu didefinisikan dalam file activity_main_drawer.xml
, yang berlokasi di app > res > menu. Tag <group></group>
mendefinisikan grup menu—kumpulan item yang memiliki ciri sama, seperti apakah mereka terlihat, aktif, atau bisa dicentang. Suatu grup harus berisi satu atau beberapa elemen <item></>
dan merupakan anak dari elemen <menu>
, seperti yang ditampilkan di bawah ini. Selain mendefinisikan setiap judul item menu dengan atribut android:title
, file juga mendefinisikan setiap ikon item menu dengan atribut android:icon
.
Grup didefinisikan dengan atribut android:checkableBehavior
. Atribut ini memungkinkan Anda meletakkan elemen interaktif dalam panel samping navigasi, seperti switch beralih yang bisa diaktifkan atau dinonaktifkan, dan kotak centang serta tombol radio yang bisa dipilih. Pilihan untuk atribut ini adalah:
single
: Hanya satu item dari grup ini yang bisa dicentang. Gunakan untuk tombol radio.all
: Semua item bisa dicentang. Gunakan untuk kotak centang.none
: Tidak ada item yang bisa dicentang.<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <group android:checkableBehavior="none"> <item android:id="@+id/nav_camera" android:icon="@drawable/ic_menu_camera" android:title="@string/import_camera" /> <item android:id="@+id/nav_gallery" android:icon="@drawable/ic_menu_gallery" android:title="@string/gallery" /> <item android:id="@+id/nav_slideshow" android:icon="@drawable/ic_menu_slideshow" android:title="@string/slideshow" /> <item android:id="@+id/nav_manage" android:icon="@drawable/ic_menu_manage" android:title="@string/tools" /> </group> <item android:title="@string/communicate"> <menu> <item android:id="@+id/nav_share" android:icon="@drawable/ic_menu_share" android:title="@string/share" /> <item android:id="@+id/nav_send" android:icon="@drawable/ic_menu_send" android:title="@string/send" /> </menu> </item> </menu>
Mempersiapkan panel samping navigasi dan listener item
Untuk menggunakan listener item menu panel samping navigasi, aktivitas yang menjadi host panel samping navigasi harus mengimplementasikan antarmuka OnNavigationItemSelectedListener:
Implementasikan
NavigationView.OnNavigationItemSelectedListener
dalam definisi kelas:public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { ... }
Antarmuka ini menawarkan metode onNavigationItemSelected(), yang dipanggil bila suatu item dalam item menu panel samping navigasi diketuk. Saat Anda memasukkan
OnNavigationItemSelectedListener
, bola lampu peringatan merah muncul pada margin kiri.Klik bola lampu peringatan merah, pilih Implement methods, dan pilih metode onNavigationItemSelected(item:MenuItem):boolean.
Android Studio akan menambahkan stub untuk metode ini:
@Override public boolean onNavigationItemSelected(MenuItem item) { return false; } }
Anda bisa mempelajari cara menggunakan stub ini di bagian berikutnya.
Sebelum mempersiapkan listener item navigasi, tambahkan kode ke metode
onCreate()
aktivitas untuk membuat instance objek DrawerLayout dan NavigationView (drawer
dannavigationView
dalam kode di bawah ini):@Override protected void onCreate(Bundle savedInstanceState) { . . . DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); if (drawer != null) { drawer.addDrawerListener(toggle); } toggle.syncState(); NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view); if (navigationView != null) { navigationView.setNavigationItemSelectedListener(this); } }
Kode di atas membuat instance ActionBarDrawerToggle, yang menggantikan sumber daya dapat digambar khusus untuk tombol Naik aktivitas dalam bilah aplikasi, dan tautkan aktivitas ke DrawerLayout. Sumber daya dapat digambar yang khusus akan muncul sebagai ikon navigasi "hamburger" jika panel samping ditutup, dan beranimasi menjadi tanda panah jika panel samping terbuka.
Catatan: Pastikan menggunakan ActionBarDrawerToggle dalam support-library-v7.appcompact, bukan versi dalam support-library-v4.Tip: Anda bisa menyesuaikan peralihan beranimasi dengan mendefinisikan drawerArrowStyle dalam tema ActionBar (untuk informasi lebih detail tentang tema ActionBar, lihat Menambahkan Bilah Aplikasi dalam dokumentasi Developer Android.
Kode di atas mengimplementasikan addDrawerListener() untuk mendengarkan kejadian panel samping terbuka dan tertutup, jadi saat pengguna mengetuk tombol dapat digambar yang khusus, panel samping navigasi akan bergeser keluar.
Anda juga harus menggunakan metode syncState() dari ActionBarDrawerToggle untuk menyinkronkan keadaan indikator panel samping. Sinkronisasi harus terjadi setelah keadaan instance DrawerLayout dipulihkan, dan di waktu lain bila keadaan berubah sedemikian rupa sehingga ActionBarDrawerToggle tidak diberi tahu.
Kode di atas diakhiri dengan menyetel listener,
setNavigationItemSelectedListener()
, untuk panel samping navigasi agar mendengar klik item.- ActionBarDrawerToggle juga memungkinkan Anda menetapkan string yang digunakan untuk menjelaskan tindakan buka/tutup panel samping untuk layanan aksesibilitas. Definisikan string berikut ini dalam file string.xml Anda:
<string name="navigation_drawer_open">Open navigation drawer</string> <string name="navigation_drawer_close">Close navigation drawer</string>
Menangani pemilihan item menu navigasi
Tulis kode dalam stub metode onNavigationItemSelected() untuk menangani pemilihan item menu. Metode ini dipanggil bila item dalam menu panel samping navigasi diketuk.
Metode ini menggunakan pernyataan if
untuk melakukan aksi yang sesuai berdasarkan id
item menu, yang bisa Anda ambil dengan menggunakan metode getItemId():
@Override
public boolean onNavigationItemSelected(MenuItem item) {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
// Handle navigation view item clicks here.
switch (item.getItemId()) {
case R.id.nav_camera:
// Handle the camera import action (for now display a toast).
drawer.closeDrawer(GravityCompat.START);
displayToast(getString(R.string.chose_camera));
return true;
case R.id.nav_gallery:
// Handle the gallery action (for now display a toast).
drawer.closeDrawer(GravityCompat.START);
displayToast(getString(R.string.chose_gallery));
return true;
case R.id.nav_slideshow:
// Handle the slideshow action (for now display a toast).
drawer.closeDrawer(GravityCompat.START);
displayToast(getString(R.string.chose_slideshow));
return true;
case R.id.nav_manage:
// Handle the tools action (for now display a toast).
drawer.closeDrawer(GravityCompat.START);
displayToast(getString(R.string.chose_tools));
return true;
case R.id.nav_share:
// Handle the share action (for now display a toast).
drawer.closeDrawer(GravityCompat.START);
displayToast(getString(R.string.chose_share));
return true;
case R.id.nav_send:
// Handle the send action (for now display a toast).
drawer.closeDrawer(GravityCompat.START);
displayToast(getString(R.string.chose_send));
return true;
default:
return false;
}
}
Setelah pengguna mengetuk pilihan di panel samping navigasi atau mengetuk di luar panel samping, metode closeDrawer() DrawerLayout akan menutup panel samping.
Daftar dan korsel
Gunakan daftar gulir, seperti RecyclerView, untuk menyediakan target navigasi bagi navigasi turunan. Daftar yang bergulir secara vertikal sering kali digunakan untuk layar yang mencantumkan cerita, dengan setiap item daftar bertindak sebagai tombol bagi setiap cerita. Untuk item materi yang lebih bersifat visual atau kaya media seperti foto atau video, Anda bisa menggunakan daftar yang bergulir secara horizontal (disebut juga dengan menu korsel). Elemen UI ini bagus untuk menyajikan item dalam suatu kumpulan (misalnya, daftar berita).
Anda akan mempelajari semua tentang RecyclerView di bab berikutnya.
Alur navigasi master/detail
Dalam alur navigasi master/detail, layar master berisi daftar item, dan layar detail menampilkan informasi detail tentang item tertentu. Navigasi turunan biasanya diimplementasikan oleh salah satu hal berikut ini:
- Menggunakan Maksud yang memulai aktivitas yang menyatakan layar detail. Untuk informasi selengkapnya tentang Maksud, lihat Maksud dan Filter Maksud dalam Panduan Developer Android.
- Saat menambahkan Aktivitas Setelan, Anda bisa memperluas PreferenceActivity untuk membuat layout master/detail dua panel agar mendukung layar lebar, dan menyertakan fragmen dalam aktivitas untuk menggantikan materi aktivitas dengan fragmen setelan. Inilah pola yang berguna jika Anda memiliki beberapa grup setelan dan harus mendukung layar berukuran tablet serta ponsel cerdas. Anda akan mempelajari tentang Aktivitas Setelan dan PreferenceActivity dalam bab berikutnya. Untuk informasi selengkapnya tentang menggunakan fragmen, lihat Fragmen dalam Panduan Developer Android.
Ponsel cerdas paling tepat untuk menampilkan satu layar setiap kalinya—seperti layar master (pada sisi kiri gambar di bawah) dan layar detail (pada sisi kanan gambar di bawah ini).
Sebaliknya, tampilan tablet, terutama saat dilihat pada orientasi lanskap, paling pas untuk menampilkan beberapa panel materi sekaligus: master di sebelah kiri, dan detail di sebelah kanan, seperti yang ditampilkan di bawah ini.
Menu opsi dalam bilah aplikasi
Bilah aplikasi umumnya berisi menu opsi, yang paling sering digunakan untuk pola navigasi bagi navigasi turunan. Bilah ini juga berisi ikon Naik dari navigasi leluhur, ikon navigasi untuk membuka panel samping navigasi, dan ikon filter untuk memfilter tampilan laman. Anda telah mempelajari cara mempersiapkan menu opsi dan bilah aplikasi dalam bab sebelumnya.
Navigasi lateral dengan tab dan gesek
Dengan navigasi lateral, Anda memungkinkan pengguna pergi dari satu saudara ke saudara yang lain (pada level yang sama dalam hierarki multitier). Misalnya, jika aplikasi Anda menyediakan sejumlah kategori cerita (seperti Top Stories, Tech News, dan Cooking, seperti yang ditampilkan dalam gambar di bawah ini), Anda mungkin ingin menyediakan bagi pengguna Anda kemampuan untuk beralih dari satu kategori ke kategori berikutnya, atau dari satu cerita terpopuler ke cerita berikutnya, tanpa harus mengarahkan kembali ke layar induk.
Dalam gambar di atas:
- Navigasi lateral dari satu layar kategori ke layar kategori lainnya
- Navigasi lateral dari satu layar cerita ke layar cerita lainnya
Contoh navigasi lateral lainnya adalah kemampuan untuk menggesek ke kiri atau kanan pada percakapan Gmail untuk menampilkan email baru atau lama dalam Inbox yang sama.
Anda bisa mengimplementasikan navigasi lateral dengan tab yang menyatakan setiap layar. Tab muncul sepanjang bagian atas layar, seperti yang ditampilkan pada sisi kiri gambar di atas, yang menyediakan navigasi ke layar lainnya. Navigasi tab adalah solusi umum untuk navigasi lateral dari satu layar anak ke layar anak lainnya yang bersaudara—di posisi yang sama dalam hierarki dan memiliki layar induk yang sama.
Tab paling tepat untuk rangkaian kecil (empat atau kurang) layar saudara. Anda bisa mengombinasikannya dengan tampilan gesek, sehingga pengguna bisa menggesek dari satu layar ke layar lainnya serta mengetuk tab.
Tab menawarkan dua manfaat:
- Karena ada tab tunggal yang lebih dulu dipilih, pengguna selalu memiliki akses ke materi tab tersebut dari layar induk tanpa navigasi lebih jauh.
- Pengguna bisa beralih dengan cepat di antara layar-layar terkait, tanpa perlu mengunjungi lagi layar induk terlebih dahulu.
Ingat praktik terbaik berikut saat menggunakan tab:
- Tab biasanya dihamparkan secara horizontal.
- Tab harus selalu memanjang di bagian atas layar, dan tidak boleh sejajar dengan bagian bawah layar.
- Tab harus menetap di semua layar yang terkait. Hanya region materi yang ditentukan yang akan berubah saat mengetuk tab, dan indikator harus tetap tersedia sepanjang waktu.
- Peralihan ke tab lain tidak boleh diperlakukan sebagai riwayat. Misalnya, jika seorang pengguna beralih dari tab A ke tab B, menekan tombol Naik pada bilah aplikasi tidak akan memilih lagi tab A, namun justru akan mengembalikan pengguna ke layar induk.
Langkah kunci untuk mengimplementasikan tab adalah:
- Mendefinisikan layout tab. Kelas utama yang digunakan untuk menampilkan tab adalah TabLayout. Kelas ini menyediakan layout horizontal untuk menampilkan tab. Anda bisa menampilkan tab di bawah bilah aplikasi.
- Mengimplementasikan Fragmen untuk setiap layar materi tab. Fragmen adalah perilaku atau bagian antarmuka pengguna dalam suatu aktivitas. Fragmen seperti aktivitas mini di dalam aktivitas utama, dengan daur hidupnya sendiri. Salah satu manfaat menggunakan fragmen untuk materi tab adalah Anda bisa mengisolasi kode untuk mengelola materi tab dalam fragmen. Untuk mengetahui tentang fragmen, lihat Fragmen dalam Panduan API.
- Menambahkan adapter pager. Gunakan kelas PagerAdapter untuk mengisi "laman" (layar) di dalam ViewPager, yaitu pengelola layout yang memungkinkan pengguna membalik ke kiri dan kanan pada layar data. Sediakan implementasi PagerAdapter untuk menghasilkan layar yang akan ditunjukkan oleh tampilan. ViewPager paling sering digunakan bersama Fragment, yang merupakan cara praktis untuk menyediakan dan mengelola daur hidup setiap layar.
- Membuat instance layout tab, dan menyetel teks untuk setiap tab.
- Menggunakan
PagerAdapter
untuk mengelola tampilan layar ("laman"). Setiap layar dinyatakan oleh fragmennya setiap. - Menyetel listener untuk menentukan tab mana yang diketuk.
Ada adapter standar untuk menggunakan fragmen bersama ViewPager:
- FragmentPagerAdapter: Didesain untuk navigasi antar layar (laman) saudara yang menyatakan jumlah layar yang tetap dan sedikit.
- FragmentStatePagerAdapter: Didesain untuk paging ke semua kumpulan layar (laman) dengan jumlah layar tidak ditentukan. Hal ini akan memusnahkan fragmen saat pengguna beralih ke layar lain, sehingga meminimalkan penggunaan memori. Aplikasi untuk tantangan praktis ini menggunakan FragmentStatePagerAdapter.
Mendefinisikan layout tab
Untuk menggunakan TabLayout, Anda bisa mendesain layout aktivitas utama untuk menggunakan Toolbar
sebagai bilah aplikasi, TabLayout
untuk tab di bawah bilah aplikasi, dan ViewPager
dalam layout akar untuk mengalihkan tampilan anak. Layout harus tampak sama dengan yang berikut ini, dengan anggapan setiap tampilan anak mengisi layar:
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
<android.support.design.widget.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/toolbar"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_below="@id/tab_layout"/>
Untuk setiap tampilan anak, buat file layout seperti tab_fragment1.xml, tab_fragment2.xml, tab_fragment3.xml, dan seterusnya.
Mengimplementasikan setiap fragmen
Fragmen adalah perilaku atau bagian antarmuka pengguna dalam suatu aktivitas. Fragmen seperti aktivitas mini di dalam aktivitas utama, dengan daur hidupnya sendiri. Untuk mengetahui tentang fragmen, lihat Fragmen dalam Panduan API.
Tambahkan kelas untuk setiap fragmen (seperti TabFragment1.java, TabFragment2.java, dan TabFragment3.java) yang menyatakan layar yang bisa dikunjungi pengguna dengan mengeklik tab. Setiap kelas harus memperluas Fragment dan memekarkan layout yang terkait dengan layar (tab_fragment1
, tab_fragment2
, dan tab_fragment3
). Misalnya, TabFragment1.java terlihat seperti ini:
public class TabFragment1 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.tab_fragment1, container, false);
}
}
Menambahkan adapter pager
Tambahkan sebuah PagerAdapter
yang memperluas FragmentStatePagerAdapter dan:
- Mendefinisikan jumlah tab.
- Menggunakan metode getItem() kelas Adapter untuk menentukan tab mana yang diklik.
- Menggunakan blok
switch case
untuk mengembalikan layar (laman) agar ditampilkan berdasarkan tab yang diklik
public class PagerAdapter extends FragmentStatePagerAdapter {
int mNumOfTabs;
public PagerAdapter(FragmentManager fm, int NumOfTabs) {
super(fm);
this.mNumOfTabs = NumOfTabs;
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new TabFragment1();
case 1:
return new TabFragment2();
case 2:
return new TabFragment3();
default:
return null;
}
}
@Override
public int getCount() {
return mNumOfTabs;
}
}
Membuat sebuah instance dari layout tab
Di metode onCreate()
dari aktivitas utama, buat instance layout tab dari elemen tab_layout
di layout, dan setel teks untuk setiap tab menggunakan addTab():
@Override
protected void onCreate(Bundle savedInstanceState) {
...
// Create an instance of the tab layout from the view.
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
// Set the text for each tab.
tabLayout.addTab(tabLayout.newTab().setText("Top Stories"));
tabLayout.addTab(tabLayout.newTab().setText("Tech News"));
tabLayout.addTab(tabLayout.newTab().setText("Cooking"));
// Set the tabs to fill the entire layout.
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
// Use PagerAdapter to manage page views in fragments.
...
}
Ekstrak sumber daya string untuk teks tab yang disetel oleh setText()
:
"Top Stories"
ketab_label1
"Tech News"
ketab_label2
"Cooking"
ketab_label3
Mengelola tampilan layar dalam fragmen dan setel listener
Gunakan PagerAdapter
dalam metode onCreate()
aktivitas utama untuk mengelola tampilan layar ("laman") dalam fragmen. Setiap layar dinyatakan oleh fragmennya setiap. Anda juga perlu menyetel listener untuk menentukan tab mana yang diketuk. Kode berikut ini harus muncul setelah kode dari bagian sebelumnya dalam metode onCreate()
:
@Override
protected void onCreate(Bundle savedInstanceState) {
...
// Use PagerAdapter to manage page views in fragments.
// Each page is represented by its own fragment.
// This is another example of the adapter pattern.
final ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
final PagerAdapter adapter = new PagerAdapter
(getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(adapter);
// Setting a listener for clicks.
viewPager.addOnPageChangeListener(new
TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
Menggunakan ViewPager untuk tampilan gesek (paging horizontal)
ViewPager adalah pengelola layout yang memungkinkan pengguna membalik "laman" (layar) materi ke kiri dan ke kanan. ViewPager paling sering digunakan bersama Fragment, yang merupakan cara praktis untuk menyediakan dan mengelola daur hidup setiap "laman". ViewPager juga menyediakan kemampuan untuk menggesek "laman" secara horizontal.
Dalam contoh sebelumnya, Anda menggunakan ViewPager
dalam layout akar untuk mengalihkan layar anak. Ini menyediakan kemampuan bagi pengguna untuk menggesek dari satu layar anak ke layar anak lainnya. Pengguna bisa beralih ke layar saudara dengan menyentuh dan menyeret layar secara horizontal dalam arah layar berdekatan yang diinginkan.
Tampilan gesek paling tepat jika ada kesamaan dalam tipe materi di antara laman yang bersaudara, dan jika jumlah saudara relatif kecil. Dalam kasus ini, pola bisa digunakan bersama tab di atas region materi untuk menunjukkan laman saat ini dan laman yang tersedia, guna membantu kemampuan untuk dapat ditemukan dan menyediakan lebih banyak konteks bagi pengguna.
Tip: Sebaiknya hindari paging secara horizontal bila layar anak berisi permukaan geser horizontal (seperti peta), karena interaksi yang saling bertentangan ini bisa menghalangi kegunaan layar Anda.
Praktik terkait
Latihan terkait dan dokumentasi praktik ada di Dasar-Dasar Developer Android: Praktik.